//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef __NAMEDCONDITION_H__
#define __NAMEDCONDITION_H__

#include <elasys_server.h>
#include <interlocked.h>
#include "namedobj.h"

class CNamedCondition: public ICondition, public NamedObject
{
// Interface functions
//
public:
    CARAPI_(PInterface) Probe(
        /* [in]  */ REIID riid);

    CARAPI_(UInt32) AddRef();

    CARAPI_(UInt32) Release();

    CARAPI Aggregate(
        /* [in]  */ AggregateType type,
        /* [in]  */ PInterface pObject);

    CARAPI GetDomain(
        /* [out] */ PInterface * ppObj);

    CARAPI Wait(
        /* [in] */ IMutex *pMutex,
        /* [out] */ WaitResult *pResult);

    CARAPI TryWait(
        /* [in] */ IMutex *pMutex,
        /* [in] */ Millisecond32 msTimeout,
        /* [out] */ WaitResult *pResult);

    CARAPI Pulse();

    CARAPI PulseAll();

public:
    PInterface    GetObject() { return (PInterface)this; }
    oid_t        GetOid()    { return m_oid; }
    ObjectType GetType()   { return ObjectType_NamedCondition;}
    Boolean    CompareName(WString name);

public:
    CNamedCondition(oid_t oid)
            : m_pName(NULL),
              m_oid(oid) { DLinkNode::Initialize(); }

    virtual ~CNamedCondition();

    ECode Initialize(
        /* [in] */ WString name);

private:
    WStringBuf * m_pName;
    oid_t m_oid;

private:
    Interlocked m_cRef;
};

class CNamedConditionFactory : public NamedObjectFactory
{
public:
    WString GetName() { return m_name; }

    ObjectType GetType() { return ObjectType_NamedCondition; }

    ECode CreateNamedObject(
            /* [out] */ NamedObject ** ppNamedObj,
            /* [out] */ Boolean * pbAlreadyExisted);

    ECode ResolveNamedObject(
            /* [in]  */ oid_t oid,
            /* [out] */ NamedObject ** ppNamedObj);

    ECode DestroyNamedObject(
            /* [in]  */ oid_t oid);
public:
    CNamedConditionFactory(
            /* [in] */ WString name)
            : m_name(name) {}

private:
    WString m_name;
};

INLINE Boolean CNamedCondition::CompareName(WString name)
{
    return m_pName->Compare(name) ? FALSE : TRUE;
}

#endif  //__NAMEDCONDITION_H__
